import asyncio
import logging
import json
import time
from mysql_AsyncMYSQL import AsyncMYSQL #协程数据库操作
import platform  # 新增：用于检测系统

# 关键：Windows 系统切换事件循环
if platform.system() == "Windows":
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

from aiomqtt import Client, MqttCodeError

# 配置日志
logging.basicConfig(
    level=logging.INFO, # 设置日志级别,只输出 INFO 及以上级别的日志
    format='%(asctime)s - %(levelname)s - %(message)s' # 设置日志格式
)
logger = logging.getLogger(__name__) # 创建日志记录器实例
client_status = {}

async def fa_message(client,topic,message,qos=1,retain=False,timeout=5 ):
    # 用try-except捕获发布过程中的异常
    try:
        # 发布消息
        await client.publish(
            topic=topic,
            payload=message,
            qos=qos,
            retain=retain,
            timeout=timeout  # 设定超时时间（10秒）
        )
        #logger.info("消息发布成功")  # 发布成功的回调

    # 捕获MQTT协议错误（如权限不足、主题无效等）
    except MqttCodeError as e:
        logger.error(f"MQTT协议错误：错误码={e.rc}，原因={e.args[0]}")

    # 捕获超时错误（超过设定的timeout时间未完成发布）
    except asyncio.TimeoutError:
        logger.error("消息发布超时（服务器未在5秒内确认）")

    # 捕获其他未知错误（如网络断开、连接已关闭等）
    except Exception as e:
        logger.error(f"发布失败：未知错误 - {str(e)}")

async def main():
    try:
        async with Client(
            hostname="192.168.1.88",  # MQTT服务器地址
            port=1883,                # 端口
            username="f001",          # 用户名
            password="cx123100",      # 密码
            identifier="fuWuQi",      # 客户端ID（aiomqtt用identifier）
            timeout=30,               # 延长超时时间
            clean_session=True
        ) as client: # as client 是将 上下文管理器返回的核心操作对象 赋值给变量 client
            logger.info("成功连接到MQTT服务器（aiomqtt异步模式）")

            # 订阅主题
            await client.subscribe([
                ("$SYS/brokers/+/clients/#", 1),
                ("cx/jia/#", 1)
            ])
            logger.info("主题订阅完成")

            # 接收消息
            async for message in client.messages:
                #topic = message.topic
                topic = str(message.topic)  # 这里必须转换为字符串
                payload = message.payload.decode('utf-8')
                logger.info(f"收到主题: {topic}，消息: {payload}")

                # 业务逻辑（保持不变）
                try:
                    payload_data = json.loads(payload)
                except json.JSONDecodeError:
                    payload_data = {"raw_data": payload}
                    logger.warning(f"payload非JSON格式: {payload}")

                # 终端上下线处理等逻辑...
                ls_message = '{"temperature": 25.5, "unit": "℃"}'
                #ls_message = "{\"temperature\": 25.5, \"unit\": \"℃\"}"
                # 首先分流
                topics = payload_data.get("topic", "topic") # 发布消息的主题
                qingQiuLeiXing = payload_data.get("qingQiuLeiXing", "qingQiuLeiXing")  # 请求类型


                if topics != "topic":

                    weiZhi = payload_data.get("weiZhi", "weiZhi") # 设备位置
                    sheBei = payload_data.get("sheBei", "sheBei") # 设备名
                    zhuangTai = payload_data.get("zhuangTai", "zhuangTai")# 设备状态
                    match topics:
                        case "cx/jia":
                            pass
                        case "cx/che":
                            pass
                        case _:
                            pass

                else:  # 终端上下线处理
                    # 解析客户端ID
                    parts = topic.split('/')
                    # 主题至少需要6个部分（如$SYS/brokers/node/clients/clientid/connected）= $SYS/brokers/emqx@172.18.0.4/clients/mqttx_7b693d31/connected
                    if len(parts) < 6:
                        return

                    client_id = parts[4]
                    # 事件类型（connected/disconnected）位于索引5
                    event_type = parts[5]

                    # 处理上线事件
                    if event_type == "connected":
                        username = payload_data.get("username", "未知")
                        logger.info(f"终端上线: {client_id},用户名: {username}")
                        # 写入数据库
                        # 发送消息到 cx/jia/temp 主题（匹配 cx/jia/# 通配符）
                        #await fa_message(client,"ssd",'{"temperature": 25.5, "unit": "℃"}')

                    # 处理下线事件
                    elif event_type == "disconnected":
                        username = payload_data.get("username", "未知")
                        logger.info(f"终端下线: {client_id},用户名: {username}")
                        #写入数据库



    except Exception as e:
        logger.error(f"连接或运行出错: {e}")


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        logger.info("程序被用户中断")
    except Exception as e:
        logger.error(f"发生异常: {e}")